home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Wavy / Wavy.c < prev    next >
C/C++ Source or Header  |  1993-06-18  |  6KB  |  247 lines

  1. /*
  2.     Wavy.c
  3.  
  4.     Make everything nice and wavy.
  5.  
  6.     Known bugs:
  7.  
  8.         If you launch applications and they call InitCursor, the cursor will disappear.
  9.             What can we do to prevent this? Perhaps switch back to the on-screen base address
  10.             whenever the cursor calls are called (patch into the low-level cursor vectors).
  11.  
  12.         Escape and Cancel do not work in the main dialog. We should really write a dialog
  13.             filter function that will make everything work.
  14. */
  15.  
  16. #include <QDOffscreen.h>
  17. #include <Retrace.h>
  18.  
  19. #include "Wavy.h"
  20.  
  21. static GDHandle        FindGoodScreen(void);
  22. static Boolean        IsGoodScreen(GDHandle);
  23. static BitMap        *CopyBitsParameter(PixMapHandle);
  24. static pascal void    ColumnTask(void);
  25.  
  26. typedef struct {
  27.     VBLTask        task;
  28.     char        *sourceBase;
  29.     char        *destinationBase;
  30.     short        columnNumber;
  31.     short        frameNumber;
  32.     short        totalColumns;
  33.     short        totalFrames;
  34.     short        width;
  35.     short        height;
  36.     short        rowBytes;
  37.     Rect        screenRect;
  38.     short        *frameCode[frameCount];
  39. } HonkinVBLTask;
  40.  
  41. static GDHandle FindGoodScreen(void)
  42. {
  43.     GDHandle    device;
  44.  
  45.     device = GetMainDevice();
  46.     if (IsGoodScreen(device))
  47.         return device;
  48.  
  49.     for (device = GetDeviceList(); device != nil; device = GetNextDevice(device))
  50.         if (IsGoodScreen(device))
  51.             return device;
  52.  
  53.     return nil;
  54. }
  55.  
  56. static Boolean IsGoodScreen(GDHandle screen)
  57. {
  58.     return (**(**screen).gdPMap).cmpSize == 8;
  59. }
  60.  
  61. static BitMap *CopyBitsParameter(PixMapHandle pixmap)
  62. {
  63.     return (BitMap *)pixmap;
  64. }
  65.  
  66. static pascal void ColumnTask(void)
  67. {
  68.     HonkinVBLTask    *task;
  69.     Rect            column;
  70.     short            hOffset;
  71.     Point            zeroOffset;
  72.  
  73.     asm {
  74.         move.l    a0,task
  75.     }
  76.  
  77.     column = task->screenRect;
  78.     hOffset = task->columnNumber * columnSize;
  79.     column.left += hOffset;
  80.     column.right = column.left + columnSize;
  81.     zeroOffset.h = 0;
  82.     zeroOffset.v = 0;
  83.     ShieldCursor(&column, zeroOffset);
  84.     DrawColumn(task->sourceBase + hOffset, task->destinationBase + hOffset, task->frameNumber, task->frameCode);
  85.     ShowCursor();
  86.  
  87.     if (++task->columnNumber >= task->totalColumns) {
  88.         task->columnNumber = 0;
  89.         if (++task->frameNumber >= task->totalFrames) {
  90.             task->frameNumber = 0;
  91.         }
  92.     }
  93.  
  94.     task->task.vblCount = 1;
  95. }
  96.  
  97. main()
  98. {
  99.     Boolean            newWaviness, enoughMemory;
  100.     GDHandle        screen;
  101.     PixMapHandle    screenPix;
  102.     short            width, height, rowBytes;
  103.     long            screenSize;
  104.     Ptr                screenBase, offscreenBase;
  105.     HonkinVBLTask    task;
  106.     EventRecord        event;
  107.     long            amplitude;
  108.     DialogPtr        dialog;
  109.     short            item;
  110.     Handle            itemHandle;
  111.     Str255            string;
  112.     short            frameNumber;
  113.     Rect            itemBox;
  114.  
  115.     InitGraf(&qd.thePort);
  116.     InitMenus();
  117.     InitWindows();
  118.     TEInit();
  119.     InitDialogs(nil);
  120.     SetMenuBar(GetNewMBar(128));
  121.     AddResMenu(GetMHandle(128), 'DRVR');
  122.     DrawMenuBar();
  123.     InitCursor();
  124.  
  125.     screen = FindGoodScreen();
  126.     if (screen == nil) {
  127.         Alert(131, nil);
  128.         return;
  129.     }
  130.  
  131.  
  132.     screenPix = (**screen).gdPMap;
  133.     width = (**screenPix).bounds.right - (**screenPix).bounds.left;
  134.     height = (**screenPix).bounds.bottom - (**screenPix).bounds.top;
  135.     rowBytes = (**screenPix).rowBytes & 0x7FFF;
  136.     if (width % columnSize != 0) {
  137.         Alert(131, nil);
  138.         return;
  139.     }
  140.  
  141.     screenSize = height * (long) rowBytes;
  142.     offscreenBase = NewPtr(screenSize);
  143.     if (offscreenBase == nil) {
  144.         Alert(130, nil);
  145.         return;
  146.     }
  147.  
  148. restart:
  149.     newWaviness = false;
  150.  
  151.     dialog = GetNewDialog(129, nil, nil);
  152.     GetDItem(dialog, 1, nil, nil, &itemBox);
  153.     InsetRect(&itemBox, -4, -4);
  154.     SetPort(dialog);
  155.     PenSize(3, 3);
  156.     FrameRoundRect(&itemBox, 16, 16);
  157.     SelIText(dialog, 3, 0, 32767);
  158.     for (;;) {
  159.         ModalDialog(nil, &item);
  160.         if (item != ok) ExitToShell();
  161.         GetDItem(dialog, 3, nil, &itemHandle, nil);
  162.         GetIText(itemHandle, string);
  163.         StringToNum(string, &litude);
  164.         if ((short)amplitude >= 1) break;
  165.     }
  166.     DisposeDialog(dialog);
  167.  
  168.     dialog = GetNewDialog(128, nil, nil);
  169.     GetDItem(dialog, 1, nil, &itemHandle, nil);
  170.     DrawDialog(dialog);
  171.     enoughMemory = InitColumns(amplitude, width, height, rowBytes, task.frameCode, itemHandle);
  172.     DisposeDialog(dialog);
  173.     if (!enoughMemory) {
  174.         Alert(130, nil);
  175.         return;
  176.     }
  177.  
  178.     screenBase = (**screenPix).baseAddr;
  179.  
  180.     HideCursor();
  181.     BlockMove(screenBase, offscreenBase, screenSize);
  182.     ShowCursor();
  183.     (**screenPix).baseAddr = offscreenBase;
  184.  
  185.     task.task.qType = vType;
  186.     task.task.vblAddr = ColumnTask;
  187.     task.task.vblCount = 1;
  188.     task.task.vblPhase = 0;
  189.     task.sourceBase = offscreenBase;
  190.     task.destinationBase = screenBase;
  191.     task.columnNumber = 0;
  192.     task.frameNumber = 0;
  193.     task.totalColumns = width / columnSize;
  194.     task.totalFrames = frameCount;
  195.     task.width = width;
  196.     task.height = height;
  197.     task.rowBytes = rowBytes;
  198.     task.screenRect = (**screenPix).bounds;
  199.     if (SlotVInstall((QElemPtr)&task, 0) != noErr) {
  200.         goto done;
  201.     }
  202.  
  203.     for (;;) {
  204.         long    menuItem = 0;
  205.  
  206.         GetNextEvent(everyEvent, &event);
  207.         if (event.what == keyDown)
  208.             menuItem = MenuKey(event.message & 0xFF);
  209.         else if (event.what == mouseDown) {
  210.             short        which;
  211.             WindowPtr    window;
  212.  
  213.             which = FindWindow(event.where, &window);
  214.             if (which == inMenuBar)
  215.                 menuItem = MenuSelect(event.where);
  216.         }
  217.         if (menuItem == ((128L<<16) | 1)) {
  218.             Alert(132, nil);
  219.         } else if (menuItem == ((129L<<16) | 1)) {
  220.             newWaviness = true;
  221.             break;
  222.         } else if (menuItem == ((129L<<16) | 3))
  223.             break;
  224.         else if ((menuItem>>16) == 128) {
  225.             Str255    name;
  226.  
  227.             GetItem(GetMHandle(128), menuItem & 0xFFFF, name);
  228.             OpenDeskAcc(name);
  229.         }
  230.         HiliteMenu(0);
  231.     }
  232.  
  233.     SlotVRemove((QElemPtr)&task, 0);
  234.  
  235.     for (frameNumber = 0; frameNumber < frameCount; ++frameNumber)
  236.         DisposePtr((Ptr)task.frameCode[frameNumber]);
  237.  
  238. done:
  239.     (**screenPix).baseAddr = screenBase;
  240.     HideCursor();
  241.     BlockMove(offscreenBase, screenBase, screenSize);
  242.     InitCursor();
  243.  
  244.     if (newWaviness)
  245.         goto restart;
  246. }
  247.